package net.toocruel.iqismart.web.controller.core;

import net.toocruel.iqismart.entity.common.Category;
import net.toocruel.iqismart.entity.constants.CategoryVisibility;
import net.toocruel.iqismart.entity.constants.SourceType;
import net.toocruel.iqismart.entity.core.Answer;
import net.toocruel.iqismart.entity.core.Comment;
import net.toocruel.iqismart.entity.core.Question;
import net.toocruel.iqismart.entity.core.QuestionInvitation;
import net.toocruel.iqismart.entity.rbac.User;
import net.toocruel.iqismart.entity.setting.Setting;
import net.toocruel.iqismart.security.core.support.Result;
import net.toocruel.iqismart.service.UserService;
import net.toocruel.iqismart.service.core.*;
import net.toocruel.iqismart.service.exception.UserRepeatException;
import net.toocruel.iqismart.web.controller.base.AbstractBaseController;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Controller
@RequestMapping("question")
public class QuestionController extends AbstractBaseController {

    @Autowired
    private UserService userService;

    @Autowired
    private TagService tagService;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private QuestionService questionService;

    @Autowired
    private CommentService commentService;

    @Autowired
    private AnswerService answerService;

    @GetMapping("create")
    public String create(Long toUserId,HttpServletRequest request,Question question){
        if(toUserId!=null && toUserId>0){
            User toUser = userService.findById(toUserId);
            request.setAttribute("toUser",toUser);
        }

        List<Category> categorys = categoryService.findByVisibilityAndRoles(CategoryVisibility.questions,getCurrentUser());

        request.setAttribute("categorys",categorys);

        //seoTitle
        request.setAttribute("seoTitle","发起提问 - "+Setting.SETTING.getWebsite().getName());

        return getTemplate("create");
    }

    @PostMapping("create")
    public String doCreate(@Valid Question question, BindingResult bindingResult,
                            HttpServletRequest request, HttpServletResponse response){
        List<FieldError> allErrors = new ArrayList<>();
        bindingResult.getFieldErrors().stream().forEach(fieldError -> {
            if(!fieldError.getField().equals("category")){
                allErrors.add(fieldError);
            }
        });

        if(CollectionUtils.isEmpty(allErrors)){
            try {
                question.setUser(getCurrentUser());
                questionService.postQuestion(question);
                return "redirect:/question/"+question.getId();
            } catch (Exception e) {
                e.printStackTrace();
                request.setAttribute("error",e);
            }
        }
        return  getTemplate("create");
    }

    @GetMapping("{id}")
    public ModelAndView detail(@PathVariable Long id,@RequestParam(defaultValue = "createdAtDesc") String sort, HttpServletRequest request){

        Question question = questionService.findById(id,getCurrentUser());

        refreshCurrentUser();

        Set<Answer> answers = question.getAnswers();
        List<Answer> answerList = answers.stream().collect(Collectors.toList());
        if(CollectionUtils.isNotEmpty(answerList)){


            if(StringUtils.isNotBlank(sort) && sort.equals("createdAtAsc")){
                Collections.sort(answerList,(Answer a1, Answer a2) -> (int)(a1.getCreatedAt() - (a2.getCreatedAt() == null?0L:a2.getCreatedAt())));
            }
            if(StringUtils.isNotBlank(sort) && sort.equals("createdAtDesc")){
                Collections.sort(answerList,(Answer a1, Answer a2) -> (int)(a2.getCreatedAt() - (a1.getCreatedAt()==null?0L:a1.getCreatedAt())));
            }

            if(StringUtils.isNotBlank(sort) && sort.equals("hot")){
                Collections.sort(answerList,(Answer a1, Answer a2) -> {
                    int order1 = 0;
                    int order2 = 0;
                    if(CollectionUtils.isNotEmpty(a1.getComments())){
                        order1  += 10;
                    }
                    if(CollectionUtils.isNotEmpty(a2.getComments())){
                        order2  += 10;
                    }
                    return order2 - order1;
                });
            }
        }

        questionService.addViews(question);


        ModelAndView modelAndView = new ModelAndView(getTemplate("detail"), "question", question);
        modelAndView.addObject("answer",new Answer());
        modelAndView.addObject("answerList",answerList);

        //seoTitle
        String seoTitle = new String(Setting.SETTING.getSeo().getQuestionTitle());
        seoTitle = seoTitle.replace("{wtbt}", question.getTitle());
        seoTitle = seoTitle.replace("{wzmc}",Setting.SETTING.getWebsite().getName());
        modelAndView.addObject("seoTitle",seoTitle);

        return modelAndView;
    }

    @PostMapping("{id}")
    public ModelAndView answer(@PathVariable Long id,
                               @Valid Answer answer,
                               BindingResult bindingResult,
                               HttpServletRequest request){

        Question question = questionService.findById(id, getCurrentUser());

        if(!bindingResult.hasErrors()){
            try {

                answer.setUser(getCurrentUser());
                answer.setQuestion(question);
                answer.setQuestionTitle(question.getTitle());
                answerService.postAnswer(answer,answer.getFollow());
                return new ModelAndView("redirect:"+request.getRequestURI());
            } catch (UserRepeatException e) {
                e.printStackTrace();
                request.setAttribute("error",e);
            }
        }

        ModelAndView modelAndView = new ModelAndView(getTemplate("detail"), "question", question);
        if(answer.getFollow() == null){
            answer.setFollow(false);
        }
        return modelAndView;
    }

    @GetMapping("{id}/comments")
    public ModelAndView comments(@PathVariable Long id,
                                 HttpServletRequest request,
                                @RequestParam(defaultValue = "10000000") int size,
                                @RequestParam(defaultValue = "1") int page,
                                @RequestParam(defaultValue = "id") String sortBy,
                                @RequestParam(defaultValue = "asc") String sortOrder){

//        Question question = questionService.findById(id,getCurrentUser());
//        Set<Comment> comments = question.getComments();

        Page<Comment> commentPage = commentService.getCommonList(SourceType.question, id, new PageRequest(page - 1, size, new Sort(Sort.Direction.fromString(sortOrder), sortBy)));

        return new ModelAndView(getTemplate("commentList"),"comments",commentPage.getContent());
    }

    @RequestMapping("suggest")
    public String suggest(String word, HttpServletRequest request){

        request.setAttribute("suggests",questionService.getSuggests(word));

        return getTemplate("suggest");
    }


    @GetMapping("edit/{id}")
    public ModelAndView edit(@PathVariable Long id,HttpServletRequest request){
        Question question = questionService.findById(id,getCurrentUser());
        List<Category> categorys = categoryService.findByVisibilityAndRoles(CategoryVisibility.questions,getCurrentUser());

        ModelAndView modelAndView = new ModelAndView(getTemplate("edit"), "question", question);
        modelAndView.addObject("categorys",categorys);

        //seoTitle
        request.setAttribute("seoTitle","编辑问题 - "+Setting.SETTING.getSeo().getQuestionTitle());

        return modelAndView;
    }
    @PostMapping("edit/{id}")
    public String doEdit(@PathVariable Long id,@Valid Question question, BindingResult bindingResult,
                           HttpServletRequest request, HttpServletResponse response){
        List<FieldError> allErrors = new ArrayList<>();
        bindingResult.getFieldErrors().stream().forEach(fieldError -> {
            if(!fieldError.getField().equals("category")){
                allErrors.add(fieldError);
            }
        });

        if(CollectionUtils.isEmpty(allErrors)){
            try {
                questionService.editQuestion(question);
                return "redirect:/question/"+question.getId();
            } catch (Exception e) {
                e.printStackTrace();
                request.setAttribute("error",e);
            }
        }
        return  getTemplate("edit");
    }

    @RequestMapping("{id}/inviteUser")
    @ResponseBody
    public Result inviteUser(@PathVariable Long id, Long userId, HttpServletRequest request) throws Exception {

        Result re = questionService.inviteUser(id, userId);

        return re;
    }

    @RequestMapping("{id}/inviteEmail")
    @ResponseBody
    public Result inviteEmail(@PathVariable Long id, String sendTo, HttpServletRequest request) throws Exception {

        Result re = questionService.inviteEmail(id, sendTo);

        return re;
    }

    //<a target="_blank" href="https://tipask.toocruel.net/people/1">宋同煜</a>&nbsp;已被邀请
    // %[argument_index$][flags][width][.precision]conversion
    @RequestMapping("{id}/invitations/part")
    @ResponseBody
    public String invitations(@PathVariable Long id, HttpServletRequest request){

        StringBuffer sb = new StringBuffer();

        Page<QuestionInvitation> invitations  = questionService.getInvitations(id);
         invitations.forEach(questionInvitation -> {
             String href =  "";
             String username = "";

             if(StringUtils.isNotBlank(questionInvitation.getToEmail())){
                 href = "mailto:"+questionInvitation.getToEmail();
                 username = questionInvitation.getToEmail();
             }


             if(questionInvitation.getToUser()!=null){
                 href = Setting.SETTING.getWebsite().getUrl()+"/people/"+questionInvitation.getToUser().getId();
                 username = questionInvitation.getToUser().getUsername();
             }

             sb.append(String.format("<div style='display:inline'><a target='_blank' href='%s'>%s</a></div>,", href,username));

         });

         sb.deleteCharAt(sb.length()-1);


        StringBuffer stringBuffer = new StringBuffer();
        String html = sb.toString();
        int i1 = 400;
        if(html.length()> i1){
            for(int i = i1; i<html.length();){
                int index = html.indexOf("<div", i);
                stringBuffer.append(html.substring(i- i1,index)).append("<br/>");
                i = index+ i1;
            }
        }else{
            stringBuffer.append(html);
        }

        if(invitations.getTotalElements()>20){
            stringBuffer.append("&nbsp;等"+invitations.getTotalElements()+"人已被邀请");
        }else {
            stringBuffer.append("&nbsp;已被邀请");
        }
        return stringBuffer.toString();
    }


    @Override
    protected String getModule() {
        return "question";
    }
}
